package cz.semjob.learning.instances.creator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cz.semjob.common.attribute.value.NominalStringAttributeValue;
import cz.semjob.common.attribute.value.StringAttributeValue;
import cz.semjob.document.AnnotatedDocument;
import cz.semjob.document.annotation.EntityAnnotation;
import cz.semjob.document.annotation.metadata.AnnotationTypeFactory;
import cz.semjob.document.annotation.metadata.Entity;
import cz.semjob.document.processing.DocumentInstance;
import cz.semjob.document.processing.DocumentSentence;
import cz.semjob.document.processing.DocumentWord;
import cz.semjob.document.processing.data.comparator.DependencyHeadComparator;
import cz.semjob.learning.data.TaxonomyLearningException;
import cz.semjob.learning.data.attribute.AInstanceAttribute;
import cz.semjob.learning.data.attribute.NominalInstanceAttribute;
import cz.semjob.learning.data.attribute.NumericInstanceAttribute;
import cz.semjob.learning.data.attribute.YesNoNominalInstanceAttribute;
import cz.semjob.learning.instances.ITextInstance;
import cz.semjob.learning.instances.LabeledTextInstance;
import cz.semjob.learning.instances.UnlabeledTextInstance;
import cz.semjob.linguistic.reader.LanguageConfig;

@Component(value = "basetextinstancecreator")
public class BaseTextInstanceCreator implements ITextInstanceCreator {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5486708654460446977L;

	@Autowired
	protected AnnotationTypeFactory annotationTypeFactory;

	protected int MAX_WORDS = 6;

	protected static final String IS_ITEM = "IsItem";
	protected static final String IS_PART_OF_LIST = "IsPartOfList";
	protected static final String PARAGRAPH_NUMBER = "ParagraphNumber";

	protected static final String HEAD_DEPENDENCY = "HeadDependency";
	protected static final String HEAD_POS = "HeadPOS";

	protected static final String LAST_WORD_DEPENDENCY = "LastWordDependency";
	protected static final String LAST_WORD_POS = "LastWordPOS";
	protected static final String LAST_WORD_CASE = "LastWordCase";

	protected static final String HEAD_DEPENDENT_WORD_DEPENDENCY = "HeadDependentWordDependency";
	protected static final String HEAD_DEPENDENT_WORD_POS = "HeadDependentWordPOS";

	protected static final String HEAD_CASE = "HeadCase";
	protected static final String HEAD_NUMBER = "HeadNumber";
	protected static final String HEAD_GENDER = "HeadGender";

	protected static final String HEAD_PROPER_NOUN = "HeadProperNoun";

	protected final static String TEXT_RELATIVE_POSITION = "TextRelativePosition";
	protected final static String SENTENCE_RELATIVE_POSITION = "SentenceRelativePosition";
	protected final static String SENTENCE_LENGTH = "SentenceLegth";
	protected final static String WORD_COUNT = "WordCount";

	protected YesNoNominalInstanceAttribute properNounAttribute = new YesNoNominalInstanceAttribute(
			HEAD_PROPER_NOUN);

	protected YesNoNominalInstanceAttribute isItemAttribute = new YesNoNominalInstanceAttribute(
			IS_ITEM);

	protected YesNoNominalInstanceAttribute isPartOfListAttribute = new YesNoNominalInstanceAttribute(
			IS_PART_OF_LIST);

	/**
	 * List of current attribute names used for instance creation.
	 */
	protected List<String> attributesNamesList;

	/**
	 * List of all possible attributes that can be used for instance creation.
	 */
	protected Map<String, AInstanceAttribute> attributesMap;

	/**
	 * List of current attributes used for instance creation.
	 */
	protected List<AInstanceAttribute> attributesList;

	@Autowired
	protected LanguageConfig languageConfig;

	private static Logger logger = Logger
			.getLogger(BaseTextInstanceCreator.class);

	public BaseTextInstanceCreator() {
		super();
		this.attributesNamesList = new ArrayList<String>();
		this.attributesList = new ArrayList<AInstanceAttribute>();
		this.attributesMap = new HashMap<String, AInstanceAttribute>();

		// attributesNamesList.add(IS_ITEM);
		attributesNamesList.add(IS_PART_OF_LIST);
		attributesNamesList.add(PARAGRAPH_NUMBER);

		attributesNamesList.add(TEXT_RELATIVE_POSITION);
		attributesNamesList.add(SENTENCE_RELATIVE_POSITION);
		attributesNamesList.add(SENTENCE_LENGTH);
		attributesNamesList.add(WORD_COUNT);
		attributesNamesList.add(HEAD_POS);
		attributesNamesList.add(HEAD_DEPENDENCY);
		attributesNamesList.add(HEAD_DEPENDENT_WORD_DEPENDENCY);
		attributesNamesList.add(HEAD_DEPENDENT_WORD_POS);
		attributesNamesList.add(HEAD_CASE);
		attributesNamesList.add(HEAD_NUMBER);
		attributesNamesList.add(HEAD_GENDER);
		attributesNamesList.add(HEAD_PROPER_NOUN);

		attributesNamesList.add(LAST_WORD_POS);
		attributesNamesList.add(LAST_WORD_DEPENDENCY);
		attributesNamesList.add(LAST_WORD_CASE);

		for (int i = 1; i < MAX_WORDS; i++) {
			String posAttributeName = "Word" + i + "POS";
			String dependencyAttributeName = "Word" + i + "Dependency";
			String caseAttributeName = "Word" + i + "Case";
			String numberAttributeName = "Word" + i + "Number";

			attributesNamesList.add(posAttributeName);
			attributesNamesList.add(dependencyAttributeName);
			attributesNamesList.add(caseAttributeName);
		}

	}

	public void initTextInstanceCreator(/* LanguageConfig languageConfig */) {
		attributesMap.put(IS_ITEM, isItemAttribute);
		attributesMap.put(IS_PART_OF_LIST, isPartOfListAttribute);
		attributesMap.put(PARAGRAPH_NUMBER, new NumericInstanceAttribute(
				PARAGRAPH_NUMBER));
		attributesMap.put(TEXT_RELATIVE_POSITION, new NumericInstanceAttribute(
				TEXT_RELATIVE_POSITION));
		attributesMap.put(SENTENCE_RELATIVE_POSITION,
				new NumericInstanceAttribute(SENTENCE_RELATIVE_POSITION));
		attributesMap.put(SENTENCE_LENGTH, new NumericInstanceAttribute(
				SENTENCE_LENGTH));
		attributesMap.put(WORD_COUNT, new NumericInstanceAttribute(WORD_COUNT));

		NominalInstanceAttribute headPosAttribute = new NominalInstanceAttribute(
				HEAD_POS, languageConfig.getPartOfSpeechAttribute().getValues());
		NominalInstanceAttribute headDependencyAttribute = new NominalInstanceAttribute(
				HEAD_DEPENDENCY, languageConfig.getRelationshipAttribute()
						.getValues());

		NominalInstanceAttribute headDependentWordPosAttribute = new NominalInstanceAttribute(
				HEAD_DEPENDENT_WORD_POS, languageConfig
						.getPartOfSpeechAttribute().getValues());
		NominalInstanceAttribute headDependentWordDependencyAttribute = new NominalInstanceAttribute(
				HEAD_DEPENDENT_WORD_DEPENDENCY, languageConfig
						.getRelationshipAttribute().getValues());

		NominalInstanceAttribute headCaseAttribute = new NominalInstanceAttribute(
				HEAD_CASE, languageConfig.getCaseAttribute().getValues());
		NominalInstanceAttribute headNumberAttribute = new NominalInstanceAttribute(
				HEAD_NUMBER, languageConfig.getNumberAttribute().getValues());
		NominalInstanceAttribute headGenderAttribute = new NominalInstanceAttribute(
				HEAD_GENDER, languageConfig.getGenderAttribute().getValues());
		NominalInstanceAttribute headProperNounAttribute = properNounAttribute;

		NominalInstanceAttribute lastWordPosAttribute = new NominalInstanceAttribute(
				LAST_WORD_POS, languageConfig.getPartOfSpeechAttribute()
						.getValues());
		NominalInstanceAttribute lastWordDependencyAttribute = new NominalInstanceAttribute(
				LAST_WORD_DEPENDENCY, languageConfig.getRelationshipAttribute()
						.getValues());
		NominalInstanceAttribute lastWordCaseAttribute = new NominalInstanceAttribute(
				LAST_WORD_CASE, languageConfig.getCaseAttribute().getValues());

		attributesMap.put(HEAD_POS, headPosAttribute);
		attributesMap.put(HEAD_DEPENDENCY, headDependencyAttribute);

		attributesMap.put(HEAD_DEPENDENT_WORD_POS,
				headDependentWordPosAttribute);
		attributesMap.put(HEAD_DEPENDENT_WORD_DEPENDENCY,
				headDependentWordDependencyAttribute);

		attributesMap.put(HEAD_CASE, headCaseAttribute);
		attributesMap.put(HEAD_NUMBER, headNumberAttribute);
		attributesMap.put(HEAD_GENDER, headGenderAttribute);
		attributesMap.put(HEAD_PROPER_NOUN, headProperNounAttribute);

		attributesMap.put(LAST_WORD_DEPENDENCY, lastWordDependencyAttribute);
		attributesMap.put(LAST_WORD_POS, lastWordPosAttribute);
		attributesMap.put(LAST_WORD_CASE, lastWordCaseAttribute);

		for (int i = 1; i < MAX_WORDS; i++) {
			String posAttributeName = "Word" + i + "POS";
			String dependencyAttributeName = "Word" + i + "Dependency";
			String caseAttributeName = "Word" + i + "Case";
			String numberAttributeName = "Word" + i + "Number";

			attributesMap.put(posAttributeName, new NominalInstanceAttribute(
					posAttributeName, languageConfig.getPartOfSpeechAttribute()
							.getValues()));
			attributesMap.put(dependencyAttributeName,
					new NominalInstanceAttribute(dependencyAttributeName,
							languageConfig.getRelationshipAttribute()
									.getValues()));
			attributesMap.put(caseAttributeName, new NominalInstanceAttribute(
					caseAttributeName, languageConfig.getCaseAttribute()
							.getValues()));
			attributesMap.put(numberAttributeName,
					new NominalInstanceAttribute(numberAttributeName,
							languageConfig.getNumberAttribute().getValues()));

		}

		updateAttributes(attributesNamesList);
	}

	public List<LabeledTextInstance> createLabeledInstancesForEntity(
			AnnotatedDocument annotatedDocument, Entity entity, boolean positive)
			throws TaxonomyLearningException {
		if (attributesList.isEmpty()) {
			initTextInstanceCreator();
		}
		logger.debug("Processing text instances for entity: " + entity);

		List<LabeledTextInstance> instances = new ArrayList<LabeledTextInstance>();
		if (annotatedDocument.getDocumentEntities().indexOf(entity) < 0) {
			logger.debug("Current document does not contains annotations for this entity, skipping");
			return instances;
		}
		List<List<DocumentWord>> annotationWords;
		if (positive) {
			annotationWords = annotatedDocument.getPositiveAnnotations(entity);
		} else {
			annotationWords = annotatedDocument.getNegativeAnnotations(entity);
		}
		for (List<DocumentWord> list : annotationWords) {

			LabeledTextInstance instance = createOneLabeledInstance(
					annotatedDocument, entity, positive, list);

			instances.add(instance);

		}
		return instances;
	}

	protected LabeledTextInstance createOneLabeledInstance(
			AnnotatedDocument annotatedDocument, Entity entity,
			boolean positive, List<DocumentWord> list, Object... dataSources)
			throws TaxonomyLearningException {

		LabeledTextInstance instance = new LabeledTextInstance(attributesList,
				annotatedDocument.getDocumentInstance());
		instance.setLabel(entity);
		instance.setPositive(positive);
		instance.setWords(list);

		for (String attrName : attributesNamesList) {
			createAttribute(attrName, annotatedDocument.getDocumentInstance(),
					list, instance);
		}
		return instance;
	}

	public LabeledTextInstance createOneLabeledInstance(
			DocumentInstance documentInstance, Entity entity, boolean positive,
			List<DocumentWord> list, Object... dataSources)
			throws TaxonomyLearningException {

		LabeledTextInstance instance = new LabeledTextInstance(attributesList,
				documentInstance);
		instance.setLabel(entity);
		instance.setPositive(positive);
		instance.setWords(list);

		for (String attrName : attributesNamesList) {
			createAttribute(attrName, documentInstance, list, instance);
		}
		return instance;
	}

	public List<LabeledTextInstance> createAllLabeledInstances(
			AnnotatedDocument annotatedDocument)
			throws TaxonomyLearningException {
		if (attributesList.isEmpty()) {
			initTextInstanceCreator();
		}
		List<LabeledTextInstance> instances = new ArrayList<LabeledTextInstance>();

		// passing through each entity
		Map<EntityAnnotation, List<DocumentWord>> annotations = annotatedDocument
				.getAnnotationMapping();
		for (EntityAnnotation entityAnnotation : annotations.keySet()) {
			LabeledTextInstance instance = new LabeledTextInstance(
					attributesList, annotatedDocument.getDocumentInstance());
			instance.setLabel(entityAnnotation.getType());
			instance.setPositive(true);
			instance.setText(entityAnnotation.getText());

			for (String attrName : attributesNamesList) {
				createAttribute(attrName,
						annotatedDocument.getDocumentInstance(),
						annotations.get(entityAnnotation), instance);
			}

			instances.add(instance);

		}
		return instances;
	}

	public List<UnlabeledTextInstance> createUnlabeledTextInstances(
			DocumentInstance documentInstance, Object... dataSources)
			throws TaxonomyLearningException {
		if (attributesList.isEmpty()) {
			initTextInstanceCreator();
		}
		List<UnlabeledTextInstance> instances = new ArrayList<UnlabeledTextInstance>();
		for (List<DocumentWord> pathWords : documentInstance
				.getAllDependecyPaths()) {
			UnlabeledTextInstance instance = createOneUnlabeledInstance(
					documentInstance, pathWords, dataSources);
			instances.add(instance);
		}
		return instances;
	}

	protected UnlabeledTextInstance createOneUnlabeledInstance(
			DocumentInstance documentInstance, List<DocumentWord> words,
			Object... dataSources) throws TaxonomyLearningException {
		UnlabeledTextInstance instance = new UnlabeledTextInstance(
				attributesList, documentInstance);
		instance.setWords(words);
		for (String attrName : attributesNamesList) {
			createAttribute(attrName, documentInstance, words, instance);
		}
		return instance;
	}

	public void createAttribute(String attrName,
			DocumentInstance documentInstance,
			List<DocumentWord> instanceWords, ITextInstance instance)
			throws TaxonomyLearningException {

		// base document attributes
		int documentLength = documentInstance.getEndIndex();
		int sentencesCount = documentInstance.getSentencesCount();

		DocumentWord firstWord = instanceWords.get(0);
		DocumentSentence sentence = firstWord.getSentence();

		DocumentWord lastWord = getLastWordInSentence(instanceWords);

		if (attrName.equals(IS_PART_OF_LIST)) {

			if (isPartOfList(instanceWords)) {
				instance.addAttributeValue(IS_PART_OF_LIST,
						new NominalStringAttributeValue(IS_PART_OF_LIST, "yes",
								isPartOfListAttribute));
			} else {
				instance.addAttributeValue(IS_PART_OF_LIST,
						new NominalStringAttributeValue(IS_PART_OF_LIST, "no",
								isPartOfListAttribute));
			}
			return;
		}
		if (attrName.equals(IS_ITEM)) {

			if (isListItem(sentence.getWord(0))) {
				instance.addAttributeValue(IS_ITEM,
						new NominalStringAttributeValue(IS_ITEM, "yes",
								isItemAttribute));
			} else {
				instance.addAttributeValue(IS_ITEM,
						new NominalStringAttributeValue(IS_ITEM, "no",
								isItemAttribute));
			}
			return;
		}
		if (attrName.equals(PARAGRAPH_NUMBER)) {
			instance.addAttributeValue(PARAGRAPH_NUMBER,
					sentence.getParagraphIndex());
			return;
		}

		if (attrName.equals(TEXT_RELATIVE_POSITION)) {
			int textPosition = firstWord.getStartIndex();
			double textRelativePosition = (double) textPosition
					/ documentLength;
			instance.addAttributeValue(TEXT_RELATIVE_POSITION,
					textRelativePosition);
			return;
		}

		if (attrName.equals(SENTENCE_RELATIVE_POSITION)) {
			int sentenceIndex = firstWord.getSentenceIndex();
			double sentenceRelativePosition = (double) sentenceIndex
					/ sentence.getWordsCount();
			instance.addAttributeValue(SENTENCE_RELATIVE_POSITION,
					sentenceRelativePosition);
			return;
		}
		if (attrName.equals(SENTENCE_LENGTH)) {
			instance.addAttributeValue(SENTENCE_LENGTH,
					sentence.getWordsCount());
			return;
		}
		if (attrName.equals(WORD_COUNT)) {
			instance.addAttributeValue(WORD_COUNT, instanceWords.size());
			return;
		}

		Collections.sort(instanceWords, new DependencyHeadComparator());

		DocumentWord headWord = instanceWords.get(0);

		if (attrName.equals(HEAD_POS)) {
			instance.addAttributeValue(HEAD_POS, headWord.getLinguisticWord()
					.getPosAttribute().getPOS());
			return;
		}
		if (attrName.equals(HEAD_DEPENDENCY)) {
			instance.addAttributeValue(HEAD_DEPENDENCY, headWord
					.getLinguisticWord().getParserAttribute()
					.getDependencyRelationship());
			return;
		}
		if (attrName.equals(HEAD_DEPENDENT_WORD_POS)) {
			if (headWord.getDependencyWord() != null) {
				instance.addAttributeValue(HEAD_DEPENDENT_WORD_POS, headWord
						.getLinguisticWord().getPosAttribute().getPOS());
			} else {
				instance.addAttributeValue(HEAD_DEPENDENT_WORD_POS,
						StringAttributeValue
								.getEmptyValue(HEAD_DEPENDENT_WORD_POS));
			}
			return;
		}
		if (attrName.equals(HEAD_DEPENDENT_WORD_DEPENDENCY)) {
			if (headWord.getDependencyWord() != null) {
				instance.addAttributeValue(HEAD_DEPENDENT_WORD_DEPENDENCY,
						headWord.getLinguisticWord().getParserAttribute()
								.getDependencyRelationship());
			} else {
				instance.addAttributeValue(HEAD_DEPENDENT_WORD_DEPENDENCY,
						StringAttributeValue
								.getEmptyValue(HEAD_DEPENDENT_WORD_DEPENDENCY));
			}
			return;
		}

		if (attrName.equals(HEAD_CASE)) {
			instance.addAttributeValue(HEAD_CASE, headWord.getLinguisticWord()
					.getPosAttribute().getCase());
			return;
		}
		if (attrName.equals(HEAD_NUMBER)) {
			instance.addAttributeValue(HEAD_NUMBER, headWord
					.getLinguisticWord().getPosAttribute().getNumber());
			return;
		}
		if (attrName.equals(HEAD_GENDER)) {
			instance.addAttributeValue(HEAD_GENDER, headWord
					.getLinguisticWord().getPosAttribute().getGender());
			return;
		}

		if (attrName.equals(HEAD_PROPER_NOUN)) {
			boolean isProperNoun = checkIsProperNoun(instanceWords);
			if (isProperNoun) {
				instance.addAttributeValue(HEAD_PROPER_NOUN,
						new NominalStringAttributeValue(HEAD_PROPER_NOUN,
								"yes", properNounAttribute));
			} else {
				instance.addAttributeValue(HEAD_PROPER_NOUN,
						new NominalStringAttributeValue(HEAD_PROPER_NOUN, "no",
								properNounAttribute));
			}
			return;
		}

		if (attrName.equals(LAST_WORD_POS)) {
			instance.addAttributeValue(LAST_WORD_POS, lastWord
					.getLinguisticWord().getPosAttribute().getPOS());
			return;
		}
		if (attrName.equals(LAST_WORD_DEPENDENCY)) {
			instance.addAttributeValue(LAST_WORD_DEPENDENCY, lastWord
					.getLinguisticWord().getParserAttribute()
					.getDependencyRelationship());
			return;
		}
		if (attrName.equals(LAST_WORD_CASE)) {
			instance.addAttributeValue(LAST_WORD_CASE, lastWord
					.getLinguisticWord().getPosAttribute().getCase());
			return;
		}

		// for (int i = 1; i < MAX_WORDS; i++) { // instanceWords.size()

		int wordIndex = attrName.charAt(4) - 48;
		String posAttributeName = "Word" + wordIndex + "POS";
		if (attrName.equals(posAttributeName)) {
			if (wordIndex < instanceWords.size()) {
				instance.addAttributeValue(posAttributeName,
						instanceWords.get(wordIndex).getLinguisticWord()
								.getPosAttribute().getPOS());
			} else {
				instance.addAttributeValue(posAttributeName,
						StringAttributeValue.getEmptyValue(posAttributeName));
			}
			return;
		}
		String dependencyAttributeName = "Word" + wordIndex + "Dependency";
		if (attrName.equals(dependencyAttributeName)) {
			if (wordIndex < instanceWords.size()) {
				instance.addAttributeValue(dependencyAttributeName,
						instanceWords.get(wordIndex).getLinguisticWord()
								.getParserAttribute()
								.getDependencyRelationship());
			} else {
				instance.addAttributeValue(dependencyAttributeName,
						StringAttributeValue
								.getEmptyValue(dependencyAttributeName));
			}
			return;
		}
		String caseAttributeName = "Word" + wordIndex + "Case";
		if (attrName.equals(caseAttributeName)) {
			if (wordIndex < instanceWords.size()) {
				instance.addAttributeValue(caseAttributeName, instanceWords
						.get(wordIndex).getLinguisticWord().getPosAttribute()
						.getCase());
			} else {
				instance.addAttributeValue(caseAttributeName,
						StringAttributeValue.getEmptyValue(caseAttributeName));
			}
			return;
		}
		String numberAttributeName = "Word" + wordIndex + "Number";
		if (attrName.equals(numberAttributeName)) {
			if (wordIndex < instanceWords.size()) {
				instance.addAttributeValue(numberAttributeName, instanceWords
						.get(wordIndex).getLinguisticWord().getPosAttribute()
						.getNumber());
			} else {
				instance.addAttributeValue(numberAttributeName,
						StringAttributeValue.getEmptyValue(numberAttributeName));
			}
			return;
		}

	}

	private boolean isPartOfList(List<DocumentWord> instanceWords) {
		boolean isSeparatorBefore = false;
		boolean isSeparatorAfter = false;
		DocumentSentence sentence = instanceWords.get(0).getSentence();
		int minSentenceIndex = sentence.getWordsCount();
		for (DocumentWord documentWord : instanceWords) {
			if (documentWord.getSentenceIndex() < minSentenceIndex) {
				minSentenceIndex = documentWord.getSentenceIndex();
			}
		}
		while (minSentenceIndex > 0) {
			DocumentWord previousWord = sentence.getWord(minSentenceIndex - 1);
			if (previousWord.getText().equals("(")
					|| previousWord.getText().equals(",")
					|| previousWord.getText().equals("a")
					|| previousWord.getText().equals("/")
					|| previousWord.getText().equals("-")
					|| previousWord.getText().equals("nebo")) {
				isSeparatorBefore = true;
				break;
			}
			minSentenceIndex--;
		}
		if (minSentenceIndex == 0) {
			isSeparatorBefore = true;
		}
		if (!isSeparatorBefore) {
			return false;
		}
		// now check separator after
		int maxSentenceIndex = 0;
		for (DocumentWord documentWord : instanceWords) {
			if (documentWord.getSentenceIndex() > maxSentenceIndex) {
				maxSentenceIndex = documentWord.getSentenceIndex();
			}
		}
		while (maxSentenceIndex < sentence.getWordsCount() - 1) {
			DocumentWord nextWord = sentence.getWord(maxSentenceIndex + 1);
			if (nextWord.getText().equals(")")
					|| nextWord.getText().equals(",")
					|| nextWord.getText().equals("a")
					|| nextWord.getText().equals("/")
					|| nextWord.getText().equals("nebo")) {
				isSeparatorAfter = true;
				break;
			}
			maxSentenceIndex++;
		}
		if (maxSentenceIndex == sentence.getWordsCount() - 1) {
			isSeparatorAfter = true;
		}
		if (!isSeparatorAfter) {
			return false;
		}
		String verb = languageConfig.getPartOfSpeechAttribute()
				.getVerbRepresentation();
		for (int i = minSentenceIndex; i < maxSentenceIndex; i++) {
			if (sentence.getWord(i).getLinguisticWord().getPosAttribute()
					.getPOS().getAttrValue().equals(verb)) {
				return false;
			}
		}
		return true;
	}

	private boolean isListItem(DocumentWord word) {
		return word.getText().equals("-");
	}

	private boolean checkIsProperNoun(List<DocumentWord> words) {
		String nounRepresentation = languageConfig.getPartOfSpeechAttribute()
				.getNounRepresentation();
		// zatial len primitivne, ale nevadi
		DocumentWord headWord = words.get(0);
		if (words.size() > 0) {
			return Character.isUpperCase(headWord.getText().charAt(0))
					&& headWord.getSentenceIndex() > 0;
		} else {
			for (DocumentWord documentWord : words) {
				if (!Character.isUpperCase(documentWord.getText().charAt(0))) {
					return false;
				}
			}
			return true;
		}
		// if
		// (headWord.getLinguisticWord().getPosAttribute().getPOS().equals(nounRepresentation))
		// {
		//
		// }
	}

	public List<AInstanceAttribute> getListOfAttributes() {
		// AL
		return attributesList;
	}

	public List<String> getDataSourcesNames() {
		return new ArrayList<String>();
	}

	protected void updateAttributes(List<String> names) {
		this.attributesList.clear();
		for (String name : names) {
			if (attributesMap.get(name) != null) {
				this.attributesList.add(attributesMap.get(name));
			}
		}
	}

	protected boolean checkDependentAnnotations(List<DocumentWord> annotation1,
			List<DocumentWord> annotation2) {
		DocumentWord currentWord = annotation2.get(0);
		while (currentWord.getDependencyWord() != null) {
			currentWord = currentWord.getDependencyWord();
			if (currentWord.equals(annotation1.get(0))) {
				return true;
			}
		}
		return false;
	}

	protected int getDependentAnnotationsDistance(
			List<DocumentWord> annotation1, List<DocumentWord> annotation2) {
		int distance = 0;
		DocumentWord currentWord = annotation2.get(0);
		while (currentWord.getDependencyWord() != null) {
			if (currentWord.equals(annotation1.get(0))) {
				logger.trace("Distance: " + annotation1.get(0).getText() + ", "
						+ annotation2.get(0).getText() + " : " + distance);
				return distance;
			}
			currentWord = currentWord.getDependencyWord();
			distance++;

		}
		return -1;
	}

	public int getAnnotationsTextDistance(List<DocumentWord> annotation1,
			List<DocumentWord> annotation2) {
		DocumentWord currentWord1 = annotation1.get(0);
		DocumentWord currentWord2 = annotation2.get(0);
		return currentWord1.getSentenceIndex()
				- currentWord2.getSentenceIndex();
	}

	private boolean checkAttributeListConstains(String attributeName) {
		for (String attrName : this.attributesNamesList) {
			if (attrName.equals(attributeName)) {
				return true;
			}
		}
		return false;
	}

	protected DocumentWord getLastWordInSentence(List<DocumentWord> words) {
		DocumentSentence sentence = words.get(0).getSentence();
		int maxSentenceIndex = -1;
		for (DocumentWord documentWord : words) {
			if (documentWord.getSentenceIndex() > maxSentenceIndex) {
				maxSentenceIndex = documentWord.getSentenceIndex();
			}
		}
		return sentence.getWord(maxSentenceIndex);
	}

	protected DocumentSentence getAnnotationSentence(List<DocumentWord> words) {
		return words.get(0).getSentence();
	}

	public void setLanguageConfig(LanguageConfig languageConfig) {
		this.languageConfig = languageConfig;
	}

	public String getName() {
		return "Not defined";
	}

	protected String getParagraphHeader(List<DocumentWord> words,
			DocumentInstance document) {
		DocumentSentence sentence = words.get(0).getSentence();
		int paragraphStart = sentence.getParagraphStartIndex();
		DocumentSentence headerSentence = document
				.getSentenceByStartIndex(paragraphStart);
		return headerSentence.getText();

		// text.las

	}

	public List<String> getAttributesNamesList() {
		return attributesNamesList;
	}

	public Map<String, AInstanceAttribute> getAttributesMap() {
		return attributesMap;
	}

	public void setMAX_WORDS(int mAX_WORDS) {
		MAX_WORDS = mAX_WORDS;
	}

	public List<AInstanceAttribute> getAttributesList() {
		return attributesList;
	}

}
